﻿using System;
using System.Linq;
using System.Threading.Tasks;

namespace Ecobee.Net.Demo
{
	class Program
	{
		// ***
		// *** Declare one instance of the API to use throughout the app. If you want to connect
		// *** to multiple accounts, you can declare multiple API instances and track each one.
		// ***
		private readonly Api _api = new Api();

		// ***
		// *** Command factory
		// ***
		private readonly ICommandFactory _commandFactory = new CommandFactory();

		// ***
		// *** 
		// ***
		static void Main(string[] args)
		{
			Program program = new Program();

			// ***
			// *** Initialize the API. Create a new application from the
			// *** ecobee web developer web site and use the key here.
			// ***
			program.Api.Version = 1;
			program.Api.BaseUri = "https://api.ecobee.com";
			program.Api.ApplicationKey = "XH0PTLXk2I89rRnTpe9Gu91oEei1idw2";// "Your_App_Key_Here";
			program.Api.ApplicationName = ".NET API Demo";
			program.Api.Access.AccessTokenChanged += program.Access_AccessTokenChanged;

			// ***
			// *** Restore the previously saved token
			// ***
			string json = Properties.Settings.Default.Token;
			if (!string.IsNullOrEmpty(json)) { program.Api.Access.LoadFrom(json); }

			// ***
			// *** Register commands
			// ***
			program.CommandFactory.RegisterCommand(typeof(RequestAuthorizeCommand));
			program.CommandFactory.RegisterCommand(typeof(RefreshTokenCommand));
			program.CommandFactory.RegisterCommand(typeof(ListThermostatsCommand));
			program.CommandFactory.RegisterCommand(typeof(ThermostatDetailsCommand));

			// ***
			// *** Initialize a key char to get the loop started...
			// ***
			ConsoleKeyInfo k = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, false);

			// ***
			// *** Loop until the user quits
			// ***
			while (k.KeyChar != 'q' && k.KeyChar != 'Q')
			{
				// ***
				// *** Clear the keyboard input buffer
				// ***
				if (Console.KeyAvailable) { var buffer = Console.ReadKey(true); }

				// ***
				// *** Display a menu of options
				// ***
				program.DisplayMenu();

				// ***
				// *** Wait for a key to be pressed
				// ***
				k = Console.ReadKey(true);

				// ***
				// *** Get the command object for the pressed key
				// ***
				ICommand command = program.CommandFactory.CreateInstance(k.KeyChar.ToString());

				if (command != null)
				{
					// ***
					// *** Execute the command
					// ***
					command.Execute(program.Api).Wait();
				}
				else
				{
					Console.WriteLine("Invalid option: '{0}'.", k.KeyChar);
				}
			}
		}

		internal void Access_AccessTokenChanged(object sender, EventArgs e)
		{
			// ***
			// *** Persist the token
			// ***
			if (this.Api.Access.IsValid)
			{
				string json = this.Api.Access.Serialize();
				Properties.Settings.Default.Token = json;
				Properties.Settings.Default.Save();
			}
		}

		internal void DisplayMenu()
		{
			Console.ForegroundColor = ConsoleColor.White;
			Console.WriteLine("Select an option:");

			foreach (var item in this.CommandFactory.Commands.OrderBy(t => t.Key))
			{
				ICommand command = this.CommandFactory.CreateInstance(item.Key);
				
				Console.ForegroundColor = ConsoleColor.Gray;
				Console.Write("[");

				Console.ForegroundColor = ConsoleColor.White;
				Console.Write(command.Key);

				Console.ForegroundColor = ConsoleColor.Gray;
				Console.Write("] ");

				Console.ForegroundColor = ConsoleColor.Yellow;
				Console.WriteLine(command.Name);
			}

			Console.ResetColor(); ;
		}

		internal ICommandFactory CommandFactory
		{
			get
			{
				return _commandFactory;
			}
		}

		internal Api Api
		{
			get
			{
				return _api;
			}
		}
	}
}
